package com.authine.cloudpivot.ext.service.invoice;

import com.authine.cloudpivot.ext.Enum.SettleApplyType;
import com.authine.cloudpivot.ext.dto.model.invoice.InvoiceApply;
import com.authine.cloudpivot.ext.dto.model.invoice.InvoiceDetail;
import com.authine.cloudpivot.ext.dto.model.invoice.InvoiceDetailBill;
import com.authine.cloudpivot.ext.dto.model.invoice.OffsetInvoiceDetail;
import com.authine.cloudpivot.ext.dto.model.settle.SettleInvoice;
import com.authine.cloudpivot.ext.dto.query.SettleApplyQuery;
import com.authine.cloudpivot.ext.service.bill.BillService;
import com.authine.cloudpivot.ext.service.bill.impl.BillServiceImpl;
import com.authine.cloudpivot.ext.service.invoice.impl.InvoiceDetailServiceImpl;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.Collection;
import java.util.List;

public interface InvoiceDetailBillService {
    BillService billService = new BillServiceImpl();
    InvoiceDetailService invoiceDetailService = new InvoiceDetailServiceImpl();

    /**
     * 根据发票明细修改对应发票账单维度明细
     * @param invoiceDetailList 发票明细
     */
    void update(List<InvoiceDetail> invoiceDetailList);

    void remove(Collection<String> invoiceDetailIds);


    void deleteBalance(String invoiceApplyId, String invoiceDetailId);

    /**
     * 根据交易ID查询可开票的账单列表.
     * 注意：由于交易维度需要获取真实已申票金额(非补差)去做可申票金额处理，所以数据可能会返回无账单ID但已申票的账单条目，
     * 如果不需要该条目则按照账单ID!=null进行过滤
     *
     * @param tradeIds 交易ID列表
     * @return 账单维度的可开票model列表 通过trade_id分组求和结果
     */
    List<InvoiceDetailBill> getCanInvoiceBill(Collection<String> tradeIds);

    /**
     * 根据发票明细创建发票明细核销账单记录
     *
     * @param applyParams 发票明细实体列表
     */
    void create(@NonNull Collection<InvoiceDetail> applyParams);

    /**
     * 根据服务费发票明细创建发票明细核销账单记录
     *
     * @param applyParams 服务费发票明细列表(交易维度)
     */
    void createService(@NonNull Collection<InvoiceDetail> applyParams);

    /**
     * 根据货物红字发票明细创建红冲发票明细核销账单记录
     *
     * @param applyParams 红字发发票明细实体列表
     */
    void offsetGoods(@NonNull List<InvoiceDetail> applyParams);

    /**
     * 根据服务费发票明细账单红冲服务费
     * @param invoice 发票申请单
     * @param offsetInvoiceDetails 服务费红冲对应的发票明细账单（invoice_detail_bill）
     * @return
     */
    InvoiceApply offsetService(@NonNull InvoiceApply invoice, @Nullable Collection<OffsetInvoiceDetail> offsetInvoiceDetails);

    /**
     * 创建服务费红冲的invoice_detail
     * @param invoiceId 源蓝票发票单ID
     * @param invoiceDetailIds 源蓝票明细ID
     * @param invoiceDetailBillList 红冲的发票明细账单列表（服务费红冲以发票明细账单维度红冲）
     * @return
     */
    List<InvoiceDetailBill> offsetServiceDetail(@NonNull String invoiceId, @Nullable Collection<String> invoiceDetailIds, @NonNull List<InvoiceDetailBill> invoiceDetailBillList);

    /**
     * 根据不同的ID类型获取对应账单维度的可结算的发票数据
     *
     * @param applyType 申请类型枚举
     * @param ids     ID列表
     * @return 可结算的发票数据
     */
    SettleInvoice getSettleInvoice(SettleApplyType applyType, Collection<String> ids);

}
